﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <memory>
#include <stdio.h>
#include <functional>
#include <atomic>
using namespace std;

struct Date
{
	int _year;
	int _month;
	int _day;
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	~Date()
	{
		cout << "~Date()" << endl;
	}
};

namespace lyj
{
	template<class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr = nullptr)
			: _ptr(ptr)
			,_count(new atomic<int>(1)) 
		{}

		template<class D>
		shared_ptr(T* ptr, D del)
			: _ptr(ptr)
			,_count(new atomic<int>(1)) 
			,_del(del)
		{}

		shared_ptr(const shared_ptr<T>& sp) // 拷贝构造
			:_ptr(sp._ptr)
			,_count(sp._count)
		{
			(*_count)++; // 让计数器++
		}
		// 像指针⼀样使⽤
		T& operator*() { return *_ptr; }
		T* operator->() { return _ptr; }
		T& operator[](size_t i) { return _ptr[i]; }
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				if (--(*_count) == 0)
				{
					delete _ptr;
					delete _count;
				}
				_ptr = sp._ptr;
				_count = sp._count;
				(*_count)++;
			}	
			return *this;
		}

		T* get() const
		{
			return _ptr;
		}

		~shared_ptr()
		{
			if (--(*_count) == 0)
			{
				//delete _ptr;
				_del(_ptr); // 删除器
				delete _count;
			}
		}
	private:
		T* _ptr;
		//int* _count; // 非原子
		atomic<int>* _count; // 原子的
		function<void(T*)> _del = [](T* ptr) {delete ptr; };
	};
}


class Fclose
{
public:
	void operator()(FILE* ptr)
	{
		cout << "fclose:" << ptr << endl;
		fclose(ptr);
	}
};

//int main()
//{
//	shared_ptr<Date> sp4(new Date(2025, 11));
//	shared_ptr<Date> sp5 = make_shared<Date>(2025, 11);
//	unique_ptr<Date> up6;
//	if (sp4) cout << "sp4: not nullptr" << endl;
//	if (!up6) cout << "up6: nullptr" << endl;
//	return 0;
//}

//int main()
//{
//	lyj::shared_ptr<Date> p1(new Date); 
//	lyj::shared_ptr<Date> p2(new Date[5], [](Date* ptr) { delete[] ptr; });
//	return 0;
//}

//int main()
//{
//	//仿函数
//	unique_ptr<FILE, Fclose> p5(fopen("Test.cpp", "r"));
//	//lambda表达式
//	auto CloseFunc = [](FILE* ptr) { fclose(ptr); };//先得到一个对象
//	unique_ptr<FILE, decltype(CloseFunc)> p6(fopen("Test.cpp", "r"));
//
//
//	shared_ptr<Date> p1(new Date[10], [](Date* ptr) { delete[] ptr; });
//	// 仿函数
//	shared_ptr<FILE> p3(fopen("Test.cpp", "r"), Fclose()); 
//	// lambda表达式
//	shared_ptr<FILE> p4(fopen("Test.cpp", "r"), [](FILE* ptr) {
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//		});
//	return 0;
//}



//int main()
//{
//	//shared_ptr<Date> p1(new Date[10]); //析构时崩溃
//	shared_ptr<Date[]> p1(new Date[10]); 
//	unique_ptr<Date[]> p2(new Date[10]);
//	shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
//	return 0;
//}

//int main()
//{
//	lyj::shared_ptr<Date> p1(new Date(2025,11));
//	lyj::shared_ptr<Date> p2(p1);
//	lyj::shared_ptr<Date> p3(new Date(2, 2, 2));
//	p1 = p3; // 正常赋值
//	p1 = p1; // 自己给自己赋值
//	p1 = p2; // p1和p2指向同一个资源，这也算自己给自己赋值
//	return 0;
//}

//int main()
//{
//	lyj::shared_ptr<Date> p1(new Date);
//	lyj::shared_ptr<Date> p2(p1);
//	/*p1->_year = 2025;
//	p2->_month = 11; */
//	lyj::shared_ptr<Date> p3(new Date(2, 2, 2));
//	//p3->_year++;
//	p1 = p3; // 正常赋值
//	p1 = p1; // 自己给自己赋值
//	p1 = p2; // p1和p2指向同一个资源，这也算自己给自己赋值
//	return 0;
//}


